import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
url = "https://ilovedata.github.io/teaching/bigdata2/data/physical_test_2018_data.csv"
physical_data = pd.read_csv(url, sep=',', encoding = 'utf-8-sig')
physical_data
CENTER_NM CERT_GBN AGE_GBN TEST_AGE TEST_SEX ITEM_F001 ITEM_F002 ITEM_F003 ITEM_F004 ITEM_F005 ITEM_F006 ITEM_F007 ITEM_F008 ITEM_F012 ITEM_F018 ITEM_F019 ITEM_F022 ITEM_F028
0 연제 참가증 성인 33 M 159.2 57.2 30.3 77.0 60.0 101.0 23.3 30.6 -6.2 22.6 27.0 186.0 53.5
1 연제 참가증 성인 48 F 155.8 52.9 29.0 70.0 80.0 130.0 27.5 30.7 8.8 21.8 18.0 149.0 58.0
2 세종 참가증 성인 22 M 175.2 96.2 32.8 109.4 85.0 141.0 48.9 52.3 -2.8 31.3 40.0 212.0 54.4
3 연제 2등급 성인 29 M 178.7 79.4 17.9 80.0 84.0 132.0 44.8 45.9 10.4 24.9 48.0 230.0 57.8
4 사하 참가증 성인 31 F 160.1 50.2 31.2 NaN 71.0 115.0 13.4 16.8 15.9 19.6 27.0 133.0 33.5
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1869 전주 참가증 청소년 18 M 179.8 79.8 15.7 87.2 93.0 139.0 34.8 38.9 6.1 24.7 NaN NaN 48.7
1870 광산 참가증 성인 29 F 156.3 51.4 28.4 74.0 67.0 134.0 24.1 30.2 1.5 21.0 8.0 163.0 58.8
1871 전주 참가증 성인 19 M 173.9 64.5 17.2 77.1 95.0 138.0 30.1 27.4 4.4 21.3 40.0 209.0 46.7
1872 부천 2등급 노인 66 F 141.3 54.9 37.6 80.6 82.0 145.0 23.4 25.2 17.3 27.5 NaN NaN 45.9
1873 사하 3등급 성인 51 F 155.5 59.9 34.7 NaN 69.0 127.0 22.4 24.2 20.8 24.8 18.0 93.0 40.4

1874 rows × 18 columns

예제

  • 체력측정 데이터에서 성인남성을 임의로 선택할 때 키가 180 이상일 가능성은?

자료의 분포 이용

  • 이 경우는 데이터에 있는 모든 남자들이 선택될 가능성이 같다. 그러므로 논리적 확률을 통하여 다음과 같이 계산할 수 있다.

\[P(키 \geq 180) = \frac{\text{키가 180 이상인 성인 남자의 수}}{\text{성인 남자의 수}}\]

adult_man = physical_data[(physical_data.TEST_SEX == "M") & (physical_data.TEST_AGE >= 19)]
over_180 = adult_man[adult_man["ITEM_F001"] >= 180]
len(over_180) / len(adult_man)
0.11521739130434783
#성인남성의 키데이터 가져오고
height_adult_man = physical_data.loc[(physical_data.TEST_SEX == "M") & (physical_data.TEST_AGE >= 19),["ITEM_F001"]]
#그냥 변수명 변경해주고
height_adult_man.columns = ["height"]
#180이상의 성인남성의 수를 인덱싱과 count메서드를 사용해서 세어주고 ,성인남성의 수도 count사용해서 세어줘서 나눠줌
height_adult_man[(height_adult_man >= 180)].count()/height_adult_man.count()
#float(height_adult_man[height_adult_man.height>=180].count()) / float(height_adult_man.count())
height    0.115217
dtype: float64

분포를 가정하고 확률 구하기

  • 성인남성의 키의 분포가 \(\mathcal{N}(172.7,6.22^2)\)을 따른다고 가정.

  • np.random.noraml(mean,std,sample_size) \(\to\) 정규분포에서 확률실험하기

  • 정규분포의 누적분포함수 사용

    1. noraml_dist = scipy.stats.norm(mean,std) (scipy.stats의 norm정규분포 객체 생성)
    2. 1 - normal_dist.cdf(180) (cdf method 사용)

\[ \begin{aligned} P(x\geq180) &= 1-p(x\leq180)\\ &=1 - \int_{-\infty}^{180}f(x)dx \\ &= 1 - \text{normal_dist.cdf}(180) \end{aligned} \]

정규분포의 확률실험 이용

N = 10000
normal_sample = np.random.normal(172.7,6.22,N)
normal_sample = pd.DataFrame({"height":normal_sample})
normal_sample
height
0 162.975279
1 170.597492
2 167.287414
3 170.448974
4 172.318689
... ...
9995 181.921406
9996 173.560580
9997 171.622013
9998 168.414076
9999 176.670686

10000 rows × 1 columns

count_180 = normal_sample[normal_sample.height >= 180].count()
count_180
height    1250
dtype: int64
count_180 / N
height    0.125
dtype: float64

정규분포의 누적분포함수 이용

mean = 172.7
std = 6.22
normal_dist = stats.norm(mean,std)
1 - normal_dist.cdf(180)
0.12027094038001529

함수와 메소드

df = pd.DataFrame({'x': [-10,2,5,-4], 'y': [1, 2, -3, 2]})
df
x y
0 -10 1
1 2 2
2 5 -3
3 -4 2
def minus2plus(x):
    if x > 0 :
        return x
    elif x<=0:
        return -x
minus2plus(0)
0
df.applymap(minus2plus)
x y
0 10 1
1 2 2
2 5 3
3 4 2
df.apply(np.mean,axis=1)
0   -4.5
1    2.0
2    1.0
3   -1.0
dtype: float64
df.sum()
x   -7
y    2
dtype: int64
df.mean()
x   -1.75
y    0.50
dtype: float64
df.std()
x    6.652067
y    2.380476
dtype: float64
def count_char(x,c):
    count = 0
    for value in x:
        if c in value:
            count = count+1
    return count
student_names = ['김철수', '이용희', '손흥민', '방탄소년', '김용희', '박서준', '김지원']
count_char(student_names, "용희")
df2 = pd.DataFrame({ 'name': student_names})
df2
name
0 김철수
1 이용희
2 손흥민
3 방탄소년
4 김용희
5 박서준
6 김지원
df2.apply(count_char,c="용희")
name    2
dtype: int64